package de.tuberlin.dima.dkey.nerdle.helper;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import de.tuberlin.dima.dkey.client.Client;
import de.tuberlin.dima.dkey.client.GTree;
import de.tuberlin.dima.dkey.util.JsonTreeHelper;

public class QueryHelper {

	JsonParser parser = new JsonParser();

	public String getPredicate(String json, boolean getLemma) {

		JsonElement answerR = parser.parse(json);

		/*
		 * get the predicate
		 */
		JsonObject predicateO = answerR.getAsJsonObject().get("predicate")
				.getAsJsonObject();

		/*
		 * get the arguments
		 */
		if (getLemma)
			return predicateO.get("lemma").getAsString();
		return predicateO.get("text").getAsString();

	}

	public String getRole(String json, String role) {

		JsonElement answerR = parser.parse(json);

		/*
		 * get the predicate
		 */
		JsonObject predicateO = answerR.getAsJsonObject().get("predicate")
				.getAsJsonObject();

		/*
		 * get the arguments
		 */
		JsonArray args = predicateO.get("arguments").getAsJsonArray();

		/*
		 * get each text
		 */
		for (int i = 0; i < args.size(); i++) {

			if (args.get(i).getAsJsonObject().get("role").getAsString()
					.equals(role))
				return args.get(i).getAsJsonObject().get("text").getAsString();

		}

		return "";
	}

	public List<String> getQueryArgs(String json) {

		List<String> foundArgs = new ArrayList<String>();

		JsonElement answerR = parser.parse(json);

		/*
		 * get the predicate
		 */
		JsonObject predicateO = answerR.getAsJsonObject().get("predicate")
				.getAsJsonObject();

		foundArgs.add(predicateO.get("lemma").getAsString());

		/*
		 * get the arguments
		 */
		JsonArray args = predicateO.get("arguments").getAsJsonArray();

		/*
		 * get each text
		 */
		for (int i = 0; i < args.size(); i++) {

			foundArgs.add(args.get(i).getAsJsonObject().get("text")
					.getAsString());

			System.out.println(args.get(i).getAsJsonObject().get("text")
					.getAsString());

		}

		return foundArgs;
	}

	/**
	 * Big TODO: this code needs to be wrapped in a function
	 */
	public List<String> query(String predicate, String subject,
			List<String> objects) {

		String queryString = "{\"predicate\":{\"text\":\"" + predicate
				+ "\",\"arguments\":[";

		if (predicate.trim().equals(""))
			queryString = "{\"predicate\":{\"arguments\":[";

		if (subject != null) {
			queryString += "{\"text\":\"" + subject + "\", \"role\":\"SBJ\"},";
		}

		if (objects != null)
			for (String object : objects) {
				queryString += "{\"text\":\"" + object + "\"},";

			}

		queryString += "]}}";

		List<String> foundJsons = new ArrayList<String>();

		System.out.println(queryString);

		/*
		 * create query
		 */
		JsonTreeHelper creator = new JsonTreeHelper();
		GTree query;
		try {
			query = creator.createTree(queryString);
		} catch (com.google.gson.stream.MalformedJsonException e) {
			System.err.println("The input Json is Malformed\n"
					+ e.getLocalizedMessage());
			return null;
		}

		if (query.isValid()) {

			/*
			 * Send query to the server
			 */
			try {
				Client client = new Client("localhost", 8080);

				long time = System.currentTimeMillis();

				client.query(query);

				BlockingQueue<String> answer = client.getReturnQueue();

				String json = answer.take();
				/*
				 * print answer IDs on result screen
				 */
				System.out.println(json);
				System.out
						.println("It took "
								+ (System.currentTimeMillis() - time)
								+ " milliseconds");

				JsonElement gooe = parser.parse(json);

				JsonArray instances = gooe.getAsJsonObject().get("response")
						.getAsJsonArray();

				/*
				 * look up all answer IDs
				 */
				for (int c = 0; c < instances.size(); c++) {

					Integer id = (Integer) instances.get(c).getAsInt();
					System.out.println(id);
				}

				/*
				 * look up all answer IDs
				 */
				for (int c = 0; c < instances.size(); c++) {

					Integer id = (Integer) instances.get(c).getAsInt();

					System.out.println(id);

					client.get(id);

					answer = client.getReturnQueue();

					try {
						String response = parser.parse(answer.take())
								.getAsJsonObject().get("response").toString();

						if (response.contains("error")) {
							client.end();
							System.err.println(response);
							return null;
						}

						if (response != null) {
							GTree tree = new GTree(response);

							foundJsons.add(creator.createJson(tree));

							String jsonRes = creator.createJson(tree);

							this.getQueryArgs(jsonRes);

							System.out.println("Json: "
									+ creator.createJson(tree));
						}

					} catch (IllegalStateException e) {
						System.out.println("JSon Parser Error: " + e);
						return null;
					}

					// taResult.append("\n\n" + answer.take());

				}

				client.end();

			} catch (Exception e) {
				e.printStackTrace();
			}

		} else {
			System.out.println("Tree is not valid");
		}

		return foundJsons;
	}
}
